Kimi WebBridge原理

目录


Kimi WebBridge 工作原理(面试解析)


1. 一句话概括

Kimi WebBridge = 本地 Daemon(Go HTTP Server) + 浏览器 Extension(Chrome Debugger API → CDP),AI Agent 通过 HTTP 发指令,Extension 在用户真实浏览器中用 CDP 执行操作,全链路 127.0.0.1 闭环,登录态不出设备。


2. 三层架构图

1
2
3
4
5
flowchart LR
A[AI Agent<br>(Claude/Gemini)] -- HTTP POST --> B[本地 Daemon<br>(Go 二进制, 127.0.0.1:10086)]
B -- JSON Response --> A
B <-- WebSocket --> C[浏览器 Extension<br>(Chrome/Edge 插件)]
C -- chrome.debugger API --> D[Chrome DevTools Protocol (CDP)<br>- Page.navigate<br>- Runtime.evaluate<br>- Input.*<br>- Accessibility.*]

3. 各层职责详解

三层架构里,Daemon 负责协议中转和会话管理,Extension 负责进入浏览器执行 CDP 指令,AI Agent 只需要面向本地 HTTP 接口发起操作。

3.1 本地 Daemon(Go 二进制)

  • 编译为原生 Mach-O / ELF 二进制,本地运行的 HTTP Server
  • 监听 127.0.0.1:10086,只接受本机请求
  • 职责:
    • 作为 AI Agent 的 HTTP 入口,接收 JSON 指令
    • 通过 WebSocket 将指令转发给浏览器 Extension
    • 等待 Extension 执行完毕,将结果以 HTTP Response 返回
    • 管理 session ↔ tab group 的映射
  • 日志示例:
1
2
3
[agent-extension-daemon] listening on 127.0.0.1:10086
[ws] extension connected
[ws] hello from extension v1.9.7 (daemon v1.9.7)

3.2 浏览器 Extension(Chrome/Edge 插件)

  • 用户安装在自己日常使用的浏览器中
  • 启动时通过 WebSocket 主动连接 Daemon(长连接,不轮询)
  • 利用 chrome.debugger 权限 attach 到标签页,获得 CDP 入口
  • 天然携带用户的所有 Cookie、Session、LocalStorage
  • 执行操作后通过 WebSocket 回传结果给 Daemon

Extension 是方案里真正接触浏览器的一层:它既能继承用户当前浏览器环境,又能通过 chrome.debugger 把高层 action 落到 CDP 命令上。

3.3 AI Agent(Claude Code / Kimi / Gemini 等)

  • 通过 curl 或代码发 HTTP POST 到 127.0.0.1:10086/command
  • 请求格式:
1
2
3
4
5
{
"action": "navigate",
"args": { "url": "https://example.com", "newTab": true },
"session": "my-task"
}
  • 支持的 action:navigatefind_tabsnapshotclickfillevaluatescreenshotnetworkuploadsave_as_pdflist_tabsclose_tabclose_session

这意味着 Agent 不需要理解浏览器插件和 CDP 的细节,只要把动作抽象成固定 action,剩下的路由和执行都交给 Daemon 与 Extension。


4. 完整调用链路

以 Agent 执行一次「打开 Kimi 首页 → 截图」为例:

  • Step 1: Agent → Daemon
1
2
curl -X POST http://127.0.0.1:10086/command
-d '{"action":"navigate","args":{"url":"https://kimi.com","newTab":true},"session":"demo"}'

这一步只是把用户意图封装成 HTTP 请求。后续执行会沿着 Daemon、Extension、CDP、浏览器页面逐层传递,再按相反方向返回结果。

  • Step 2: Daemon → Extension(WebSocket)
    转发 navigate 指令
  • Step 3: Extension → 浏览器(CDP)
    chrome.debugger.attach({tabId})
    chrome.debugger.sendCommand({tabId}, 'Page.navigate', {url: 'https://kimi.com'})
  • Step 4: 浏览器 → Extension(CDP Response)
    页面加载完成
  • Step 5: Extension → Daemon(WebSocket)
    {success: true, url: "https://kimi.com", tabId: xxx}
  • Step 6: Daemon → Agent(HTTP Response)
    {success: true, url: "https://kimi.com", tabId: xxx}
  • Step 7: Agent 发起截图
    {"action":"screenshot","args":{"format":"png"}}
    → Daemon → Extension → CDP Page.captureScreenshot → 返回 base64

全程都在本机 127.0.0.1 闭环。


5. CDP 协议映射表

WebBridge 对外暴露的是语义化 action,对内再映射到不同 CDP 域。面试时重点说明:Agent 调 action,Extension 负责翻译成具体 CDP Method。

WebBridge ActionCDP 域CDP Method说明
navigatePagePage.navigate导航到指定 URL
snapshotAccessibilityAccessibility.getFullAXTree获取无障碍树(非 DOM),元素用 @ae ref 定位
clickInputInput.dispatchMouseEvent合成鼠标事件
fillRuntimeRuntime.evaluateJS 设置 .value + dispatchEvent('input')
evaluateRuntimeRuntime.evaluate在页面上下文执行任意 JS
screenshotPagePage.captureScreenshot页面截图,返回 base64
networkNetworkNetwork.enable + 事件监听启用网络监控后监听 request/response
save_as_pdfPagePage.printToPDF渲染当前页面为 PDF

6. 会话隔离机制

  • 每个 session 名映射到浏览器的一个 Tab Group
  • 不同 session 操作不同 tab group,互不干扰
  • 同一 session 下的连续操作共享同一个 tab
  • 示例:
1
2
{"action":"navigate","args":{"url":"https://a.com"},"session":"task-a"}
{"action":"navigate","args":{"url":"https://b.com"},"session":"task-b"}
  • task-a 和 task-b 在不同的 tab group 中并行执行

7. 为什么用 Extension + CDP 而不是裸 CDP

这个选择本质上是在降低用户接入成本:裸 CDP 更直接,但要求用户用特殊参数启动浏览器;Extension 方案多了一层插件,却能做到装一次后长期可用。

对比维度裸 CDP(--remote-debugging-portKimi WebBridge 方案
启动方式需要用户手动加 --remote-debugging-port=9222 启动参数Extension 随浏览器自启,零感知
安全暴露监听端口可被局域网访问(如有端口转发)只走本机 127.0.0.1:10086
用户感知每次启动浏览器都要记住加参数装一次 Extension,永久生效
版本绑定不绑定Daemon + Extension 版本 1:1 配对

核心:Extension 的 chrome.debugger 权限 = CDP 入口门票,无需改浏览器启动参数。


8. 数据安全保障

安全设计围绕一个原则展开:页面数据和登录态只在本机浏览器、Extension、Daemon 之间流转,不把浏览器上下文上传到远端服务。

  • 网络边界:Daemon 只监听 127.0.0.1,外部网络无法访问
  • 数据闭环:登录态、Cookie、页面内容全程不离开用户设备
  • 仅有的外连:匿名化的遥测事件(webbridge_daemon_alivewebbridge_command_call),只上报 tool 名称和 session 名,不包含页面内容

9. isTrusted 限制(产品边界)

Kimi WebBridge 走的是 DOM 合成事件(el.click()dispatchEvent),所以:

1
event.isTrusted === false // Kimi WebBridge 产生的所有事件

后果:

  • ✅ 绝大多数网站正常响应(React/Vue 的事件委托机制不依赖 isTrusted
  • ❌ 银行级安全控件、CAPTCHA 验证码等检查 event.isTrusted 的站点无法自动化
  • 官方定性为 产品边界,不是 bug——因为要产生 isTrusted=true 的事件需要操作系统级的输入注入,会引入安全风险

10. 面试高频追问

下面这些问题主要考察三点:通信模型、会话管理、以及为什么用无障碍树作为页面状态表示。

Q1: Extension 和 Daemon 之间为什么用 WebSocket 而不是 HTTP?

A: Extension 不能开 HTTP Server(浏览器安全限制),所以 Extension 主动发起 WebSocket 连接连到 Daemon。WebSocket 是全双工长连接,Daemon 有指令时直接 Push,Extension 执行完直接 Push 回去,不需要轮询。

Q2: 多少个 Daemon 实例?

A: 一个。Daemon 以单进程运行,通过 pid 文件防止重复启动。所有 session 共享同一个 Extension WebSocket 连接。

Q3: snapshot 为什么返回无障碍树而不是 DOM?

A: ① 无障碍树比 DOM 小得多(语义摘要 vs 完整 HTML),节省 Agent 上下文窗口;② @ae ref 基于语义角色定位,不像 CSS 选择器受 class hash 变化影响;③ LLM 理解无障碍树的效果好于解析 DOM。

Q4: 多 tab 并行时如何处理?

A: Extension 对每个 tab 独立调用 chrome.debugger.attach(tabId),CDP 协议天然支持多 target。Daemon 通过 session 名路由到正确的 tabId。


11. 与 nanobot browser_v4 架构对比

对比 nanobot browser_v4 时,核心不是谁更先进,而是两套方案服务的场景不同:Kimi WebBridge 偏用户真实浏览器接入,nanobot browser_v4 偏可控、可并发、可程序化的企业自动化环境。

11.1 架构全景对比

1
2
3
4
5
6
7
8
9
10
11
12
13
flowchart LR
subgraph Kimi WebBridge
A[Agent<br>click/type/nav/select/scroll/keys] -- HTTP --> B[Daemon]
B -- WS --> C[Extension]
C -- CDP --> D[真实浏览器]
end

subgraph nanobot browser_v4
E[Agent] -- SDK event bus --> F[Chrome Agent 同进程]
E -- 直接 CDP hover/dblclick/eval/cookie/bbox --> G[Chromium 独立实例]
F -- chrome.debugger --> G
H[Playwright] -- CDP WebSocket --> G
end

Kimi WebBridge 用 attach() 用用户的真实浏览器;nanobot 自启动独立 Chromium 实例。

11.2 核心差异对比表

维度Kimi WebBridgenanobot browser_v4
架构层数三层:Agent → Daemon → Extension → Chrome两层:Agent → SDK/Playwright → Chromium
浏览器来源用户真实浏览器(已登录)自启动独立 Chromium(需程序化登录)
CDP 接入方式chrome.debugger.attach() – Extension 间接获取Playwright 启动时建立 CDP WebSocket – 直接持有
登录态天然继承,零成本BUC REST API → JWT → CDP Network.setCookie 注入
事件可信度isTrusted=false(JS 合成事件)isTrusted=true(CDP Input.dispatchMouseEvent 内核级事件)
会话隔离Tab Group(同浏览器不同标签组)独立 user_data_dir(完全隔离的浏览器实例)
部署依赖Go Daemon + Chrome Extension + 浏览器Python + Chromium binary(自包含)
状态表示Accessibility tree + @ae ref 引用SDK DOM 序列化 + [index] 数字索引 + overlay 优先渲染
反检测无(用户真实浏览器,无自动化特征)--disable-blink-features=AutomationControlled

这张表可以按“浏览器来源、登录态、事件可信度、会话隔离”四条主线来讲,基本覆盖了两种架构取舍的重点。

11.3 事件可信度 - 最大的架构差异

Kimi WebBridge 的 click/fill 走 el.click() + dispatchEvent,产生的事件 isTrusted=false。银行、验证码等安全敏感站点会检测这个。

nanobot V4 走 CDP Input.dispatchMouseEvent / Input.dispatchKeyEvent,这些是浏览器内核级别的输入事件,isTrusted=true,和真实用户点击无区别。

1
2
Kimi: JS → el.click() → isTrusted=false (合成事件)
nanobot: CDP → Input.dispatchMouse → isTrusted=true (内核级事件)

面试话术: Kimi 选了 Extension 路线拿到用户真实登录态,代价是事件注入只能走 JS 层,isTrusted 永远是 false。我们选了 Playwright + 独立 Chromium 路线,获得内核级事件可信度。

11.4 登录态 - 零成本 vs 程序化

Kimi 直接操作用户的浏览器,Cookie/Session 天然存在。nanobot 启动全新 Chromium,需要完整的登录流程:

  1. BUC REST API 获取 JWT(HMAC-SHA256 签名 + RSA 加密密码)
  2. 通过 CDP Network.setCookie 注入到 .alipay.com / .alipay-inc.com / .antgroup-inc.cn
  3. JWT 过期前 30 分钟自动刷新,LRU 缓存管理 token

面试话术: Kimi 的 Extension 方案天然继承登录态,这是它的核心优势。我们的场景是企业内网,需要支持多账号切换和并发会话,所以选择了 API 程序化登录 + 独立浏览器实例。

11.5 为什么 Kimi 要三层,我们只要两层?

Kimi 的三层架构解决了三个问题:

  1. AI Agent 只能发 HTTP,不能直接连 WebSocket → Daemon 做 HTTP→WS 转换
  2. Extension 不能开 HTTP Server → Daemon 做本地监听
  3. 需要统一会话管理 → Daemon 做 session→Tab Group 映射

nanobot 不需要 Daemon 层,因为:

  1. Agent 和 browser-use SDK 在同一进程,直接函数调用,不需要 HTTP 中转
  2. SDK 内部管理 Playwright 连接,不需要 Extension 中转
  3. contextvars 做协程级会话隔离,不需要额外的 session 管理层

面试话术: Kimi 的 Daemon 层本质是一个协议适配器,解决的是 Agent 和 Extension 之间通信协议不匹配的问题。我们因为 Agent 和浏览器驱动在同一个 Python 进程里,所以可以省去中间层。

11.6 状态表示差异

两套方案都需要把页面压缩成 Agent 能理解的文本状态,但取数来源不同:Kimi 更依赖浏览器无障碍树,nanobot V4 更依赖 SDK 的 DOM 序列化和自定义 overlay 处理。

对比项Kimi WebBridgenanobot V4
数据源Accessibility tree(Accessibility.getFullAXTreeSDK DOM 序列化 + JS overlay 检测
元素引用@ae ref 属性(语义角色定位)[index] 数字索引(selector_map)
特殊处理overlay 优先渲染(z-index 扫描,确保 LLM 优先看到弹窗)
截断策略-30k 字符截断,overlay 内容优先保留

nanobot V4 的 overlay 优先渲染是一个实用优化:JS 扫描 body 直接子元素的 z-index,找到最顶层的 modal/drawer/popover,将其内容放在状态描述最前面。

11.7 反检测策略对比

  • Kimi: 用户真实浏览器 → 无 navigator.webdriver → 无自动化特征,但 isTrusted=false → 可被前端 JS 检测
  • nanobot: 启动参数 --disable-blink-features=AutomationControlled 覆盖 navigator.webdriver = false,但 Chrome DevTools 标记仍可能被高级检测发现,优势是 isTrusted=true → 内核级事件不可被前端区分

11.8 nanobot V4 双协议栈设计

nanobot V4 并没有只用一种协议,而是SDK + CDP 双栈

操作类型走 SDK event bus走直接 CDP
导航NavigateToUrlEvent-
点击ClickElementEvent / ClickCoordinateEvent-
输入TypeTextEvent-
下拉选择SelectDropdownOptionEvent-
滚动ScrollEvent-
快捷键SendKeysEvent-
悬停/双击/右键-Input.dispatchMouseEvent
逐字输入-Input.dispatchKeyEvent + insertText
JS 执行-Runtime.evaluate
Cookie 管理-Network.getCookies / setCookie
元素取值-DOM.resolveNode + Runtime.callFunctionOn
获取坐标-DOM.getBoxModel
滚动到可见-DOM.scrollIntoViewIfNeeded

设计原则:SDK 能做的走 SDK(事件语义清晰、状态同步好),SDK 不暴露的走 CDP(灵活但需手动管理状态)。


12. 对比深度追问

这部分适合在面试里把“为什么不直接照搬 Kimi”讲清楚:不是否定 Extension 方案,而是说明企业 Agent 场景更看重隔离、并发和可运维性。

Q1: 为什么不采用 Kimi WebBridge 的 Extension 方案?

A: 三个原因。① 企业场景需要多账号并发,Extension 方案的 Tab Group 隔离力度不够,Cookie 会串扰;② 我们的 Agent 和浏览器驱动在同一进程,不需要中间的 Daemon 协议转换层;③ 安全敏感操作(如支付验证)需要 isTrusted=true 的内核级事件,Extension 方案做不到。

Q2: nanobot 的会话隔离为什么用独立 user_data_dir 而不是 Tab Group?

A: Tab Group 共享同一个浏览器进程和 Cookie Store,不同 session 的 Cookie、LocalStorage、SessionStorage 会互相影响。独立 user_data_dir 是完全隔离的浏览器沙箱,支持同一设备上同时登录多个企业账号,不会有状态污染。

Q3: overlay 优先渲染是怎么做的?

A: V4 在返回 DOM 状态前,先跑一段 JS 扫描 document.body 的直接子元素,按 z-index 排序找到最顶层的 modal/drawer/popover。然后把这部分 DOM 提取到状态描述最前面,最后做 30k 字符截断时优先保留 overlay 内容,确保 LLM 不会忽略弹窗。

Q4: nanobot 的 BUC 登录流程具体怎么做的?

A: 四步。① 用 RSA 公钥加密密码;② 用 HMAC-SHA256 签名请求参数,调用 BUC REST API sso/login;③ 拿到 JWT(IAM_TOKEN)后,通过 CDP Network.setCookie 写入所有相关域名;④ 启动一个后台定时器,JWT 剩余有效期小于 30 分钟时自动刷新。

前四个问题回答完后,可以自然收束到架构选择本身:同样是浏览器自动化,不同业务场景会导向不同的工程取舍。

Q5: 如果让你重新设计,会怎么选?

A: 取决于场景。面向 C 端用户(Kimi 的场景),Extension 方案体验更好——零配置、继承登录态、用户无需理解浏览器自动化。面向企业 Agent 场景(我们的场景),多账号并发、事件可信度、可运维性更重要,所以选择 Playwright + 独立 Chromium + 程序化登录。

总结一句话: Kimi WebBridge 用”三层中转 + 真实浏览器”换取零成本登录态,代价是 JS 层事件不可信;nanobot V4 用”两层直连 + 自启动 Chromium”换取内核级事件可信度和强会话隔离,代价是需要程序化登录。

引用